﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sispe.Entities;
using System.Data;
using System.Data.Entity.Validation;

namespace Sispe.Repository
{
    public class UsuarioRepository : MasterRepository, IUsuarioRepository
    {

        public List<USUARIO> GetAllFromUsuario()
        {
            var query = from c in context.USUARIOs.Include("TRABAJADOR")
                            .Include("ROL")
                            .Include("USUARIO_MENU.MENU")
                            .Include("TRABAJADOR.PERSONA")
                        select c;
            return query.ToList();
        }

        public List<USUARIO> GetFromUsuarioByTrabajador(string descripcion)
        {
            if (descripcion != "")
            {
                var query = from c in context.USUARIOs.Include("TRABAJADOR").Include("ROL")
                            where c.TRABAJADOR.PERSONA.Nombres.ToUpper().Contains(descripcion.ToUpper()) ||
                                  c.TRABAJADOR.PERSONA.ApeMaterno.ToUpper().Contains(descripcion.ToUpper()) ||
                                  c.TRABAJADOR.PERSONA.ApePaterno.ToUpper().Contains(descripcion.ToUpper()) ||
                                  c.TRABAJADOR.PERSONA.Dni.ToUpper().Contains(descripcion.ToUpper())
                            select c;
                return query.ToList();
            }
            else
            {
                var query = from c in context.USUARIOs.Include("TRABAJADOR").Include("ROL")
                            select c;
                return query.ToList();
            }
        }

        public List<USUARIO> GetFromUsuarioByRol(string descripcion)
        {
            if (descripcion != "")
            {
                var query = from c in context.USUARIOs.Include("TRABAJADOR").Include("ROL")
                            where c.ROL.Descripcion.ToUpper().Contains(descripcion.ToUpper())
                            select c;
                return query.ToList();
            }
            else
            {
                var query = from c in context.USUARIOs.Include("TRABAJADOR").Include("ROL")
                            select c;
                return query.ToList();
            }
        }

        public USUARIO GetAllFromUsuarioByPersonaId(string dni)
        {
            var query = from c in context.USUARIOs.Include("TRABAJADOR.PERSONA")
                            .Include("ROL")
                            .Include("USUARIO_MENU.MENU")
                        where c.TRABAJADOR.PERSONA.Dni == dni
                        select c;

            return query.SingleOrDefault();
        }

        public bool ExistDuplicidadUsuario(string idpersona, int numero)
        {
            var query = from c in context.USUARIOs
                        where c.TRABAJADOR.PERSONA.Dni.ToUpper().CompareTo(idpersona.ToUpper()) == 0 && c.Numero != numero
                        select c;
            return query.Any();
        }

        public bool ExisteUsuario(string dni, string password)
        {
            var query = from c in context.USUARIOs
                        where c.TRABAJADOR.PERSONA.Dni.ToUpper().CompareTo(dni.ToUpper()) == 0 &&
                              c.Contraseña.ToUpper().CompareTo(password.ToUpper()) == 0
                        select c;
            return query.Any();
        }

        public bool ExisteUsuarioRol(int personaId)
        {
            var query = from c in context.USUARIOs
                        where c.IdTrabajador == personaId
                        select c;
            return query.Any();
        }

        public bool PasswdCorrecta(string password)
        {
            var query = from c in context.USUARIOs
                        where c.Contraseña.ToUpper().CompareTo(password.ToUpper()) == 0
                        select c;
            return query.Any();
        }

        public void AddUsuario(USUARIO usuario)
        {
            usuario.AREA_LIQUIDACION = null;
            usuario.TRABAJADOR = null;
            //context.Entry(usuario.TRABAJADOR.PERSONA.ESTADO_CIVIL).State = EntityState.Unchanged;
            //context.Entry(usuario.TRABAJADOR.PERSONA.SEXO).State = EntityState.Unchanged;
            //context.Entry(usuario.TRABAJADOR.PERSONA).State = EntityState.Detached;
            //context.Entry(usuario.TRABAJADOR).State = EntityState.Detached;
            //context.Entry(usuario.AREA_LIQUIDACION).State = EntityState.Detached;
            //context.Entry(usuario.TRABAJADOR).State = EntityState.Unchanged;
            foreach (var item in usuario.USUARIO_MENU)
            {
                item.MENU = null;
                item.USUARIO = null;

                context.Entry(item).State = EntityState.Added;
            }

            //var trab = (from t in context.TRABAJADORs.Include("PERSONA")
            //            where t.Id.Equals(usuario.IdTrabajador)
            //            select t).SingleOrDefault();

            //usuario.TRABAJADOR = trab;

            //usuario.TRABAJADOR = null;

            context.USUARIOs.Add(usuario);
            try
            {
                context.SaveChanges();
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException e)
            {

                var outputLines = new List<string>();
                foreach (var eve in e.EntityValidationErrors)
                {
                    outputLines.Add(string.Format(
                        "{0}: Entity of type \"{1}\" in state \"{2}\" has the following validation errors:",
                        DateTime.Now, eve.Entry.Entity.GetType().Name, eve.Entry.State));
                    foreach (var ve in eve.ValidationErrors)
                    {
                        outputLines.Add(string.Format(
                            "- Property: \"{0}\", Error: \"{1}\"",
                            ve.PropertyName, ve.ErrorMessage));
                    }
                }
                if (System.IO.File.Exists(@"D:\errors.txt"))
                {
                    System.IO.File.Delete(@"D:\errors.txt");
                    System.IO.File.AppendAllLines(@"d:\errors.txt", outputLines);
                }
                else
                {
                    System.IO.File.AppendAllLines(@"d:\errors.txt", outputLines);
                }
                throw;
            }
        }

        public void UpdateUsuario(USUARIO usuario)
        {
            //context.Entry(usuario.TRABAJADOR).State = EntityState.Detached;
            //context.Entry(usuario.ROL).State = EntityState.Detached;
            //context.Entry(usuario.AREA_LIQUIDACION).State = EntityState.Detached;
            usuario.TRABAJADOR = null;
            usuario.ROL = null;
            usuario.AREA_LIQUIDACION = null;

            foreach (var item in usuario.USUARIO_MENU)
            {
                item.MENU = null;
                item.USUARIO = null;

                context.Entry(item).State = item.Id ==
                    Int32.Parse("0") ?
                    EntityState.Added : EntityState.Modified;

                item.IdMenu = item.IdMenu;
            }
            context.Entry(usuario).State = EntityState.Modified;
            try
            {
                context.SaveChanges();
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException e)
            {

                var outputLines = new List<string>();
                foreach (var eve in e.EntityValidationErrors)
                {
                    outputLines.Add(string.Format(
                        "{0}: Entity of type \"{1}\" in state \"{2}\" has the following validation errors:",
                        DateTime.Now, eve.Entry.Entity.GetType().Name, eve.Entry.State));
                    foreach (var ve in eve.ValidationErrors)
                    {
                        outputLines.Add(string.Format(
                            "- Property: \"{0}\", Error: \"{1}\"",
                            ve.PropertyName, ve.ErrorMessage));
                    }
                }
                if (System.IO.File.Exists(@"D:\errors.txt"))
                {
                    System.IO.File.Delete(@"D:\errors.txt");
                    System.IO.File.AppendAllLines(@"d:\errors.txt", outputLines);
                }
                else
                {
                    System.IO.File.AppendAllLines(@"d:\errors.txt", outputLines);
                }
                throw;
            }
        }

        public void DeleteUsuario(int numero)
        {
            var existe = context.USUARIOs.Where(p => p.Numero.Equals(numero)).SingleOrDefault();

            if (existe != null)
            {
                context.USUARIOs.Remove(existe);
                context.SaveChanges();
            }
        }

        public void UpdatePasswdUsuario(USUARIO usuario)
        {
            usuario.TRABAJADOR = null;
            usuario.USUARIO_MENU = null;

            context.Entry(usuario).State = EntityState.Modified;
            context.SaveChanges();
        }


        public USUARIO GetFromUsuarioByIdTrabajador(int IdTrabajador)
        {
            var query = from p in context.USUARIOs.Include("ROL")
                            .Include("AREA_LIQUIDACION")
                            .Include("TRABAJADOR")
                            .Include("TRABAJADOR.PERSONA")
                            .Include("USUARIO_MENU")
                            .Include("USUARIO_MENU.MENU")
                        where p.IdTrabajador == IdTrabajador
                        select p;

            return query.SingleOrDefault();
        }
    }
}
